
#include "clock.h"
#include "freertos/FreeRTOS.h"  //FreeRTOS固件库
#include "freertos/task.h"  //延时函数需要用到该头文件
#include <stdio.h>
#include <string.h>
#include "driver/gpio.h"

#include "esp_log.h"
#include "driver/i2c.h"

#define I2C_MASTER_TIMEOUT_MS 1000  // 1秒的超时时间


//12=>0x12
uint8_t PCD85063TP_decToBcd(uint8_t val)
{
  return ( (val/10*16) + (val%10) );
}
 
//0x12=>12
uint8_t PCD85063TP_bcdToDec(uint8_t val)
{
  return ( (val/16*10) + (val%16) );
}


 esp_err_t PCF85063_register_read(uint8_t reg_addr, uint8_t *data, size_t len)
{
    return i2c_master_write_read_device(I2C_NUM_0, PCF85063_SENSOR_ADDR, &reg_addr, 1, data, len, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
}


esp_err_t PCF85063_register_write(uint8_t reg_addr, uint8_t *data,int len)
{
    int ret = 0;
    uint8_t *wr_dat = (uint8_t*) malloc(len+1);
 
    if(wr_dat==NULL)
      return -1;
 
    wr_dat[0] = reg_addr;
 
    for(int i=0;i<len;i++)
    {
        wr_dat[i+1] = data[i];
    }
    ret = i2c_master_write_to_device(I2C_NUM_0, PCF85063_SENSOR_ADDR, wr_dat, len+1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
    
    free(wr_dat);
 
    return ret;
}

int PCF85063_get_Week(int y,int m,int d)
{
  int week = 0;
  if(m==1 || m == 2)
  {
    m += 12;
    y--;
  }
  week=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7;
  //ret=0   星期天
  //ret=N   星期N
  return (week+1)%7;
}

//设置时间结构体,isAutoCalcWeek自动计算星期几
void PCF85063_setTime(CTime tm,int isAutoCalcWeek)
{
  uint8_t data[7] = {0};
  if (isAutoCalcWeek)
  {
    tm.nWeek = PCF85063_get_Week(tm.nYear, tm.nMonth, tm.nDay);
  }
  bool flag_19xx = true;
  uint16_t yr = tm.nYear;
  if (tm.nYear >= 2000)
  {
    flag_19xx = false;
    yr -= 2000;
  }
  else
  {
    yr -= 1900;
  }
 
  data[0] = PCD85063TP_decToBcd(tm.nSec);
  data[1] = PCD85063TP_decToBcd(tm.nMin);
  data[2] = PCD85063TP_decToBcd(tm.nHour);
  data[3] = PCD85063TP_decToBcd(tm.nDay);
  data[4] = PCD85063TP_decToBcd(tm.nWeek);
  data[5] = PCD85063TP_decToBcd(tm.nMonth);
  data[6] = PCD85063TP_decToBcd(yr);
 
  if (flag_19xx)
  {
    data[5] |= 0x80;
  }
 
  PCF85063_register_write(PCF85063_SEC_REG_ADDR, data, 7);
 
}

//获取年月日时分秒
bool PCF85063_getTime(CTime *tm)
{
    uint8_t data[7] = {0};
 PCF85063_register_read(PCF85063_SEC_REG_ADDR, data,7);
    
    bool flag_19xx = (data[5] >> 7) & 0x01; // Year:19XX_Flag
    bool flag_vl = (data[0] >> 7) & 0x01;   //(Voltage Low)VL=1:初始数据不可靠
    
    tm->nSec   = PCD85063TP_bcdToDec( data[0]&0x7f );
    tm->nMin   = PCD85063TP_bcdToDec( data[1]&0x7f );
    tm->nHour  = PCD85063TP_bcdToDec( data[2]&0x3f );
    tm->nDay   = PCD85063TP_bcdToDec( data[3]&0x3f );
    tm->nWeek  = PCD85063TP_bcdToDec( data[4] );
    tm->nMonth = PCD85063TP_bcdToDec( data[5]&0x1f );
    tm->nYear  = PCD85063TP_bcdToDec( data[6] ); //0~99
    
    if (flag_19xx)
    {
     tm->nYear += 1900;
    }
    else
   {
    tm->nYear += 2000;
   }
    return flag_vl;
}


//格式1: 20xx/xx/xx xx:xx:xx
//格式0: xx:xx:xx
char *PCF85063_getTmString(int isYMD)
{
   char tmStr[25]={0};
   CTime tm;
   PCF85063_getTime(&tm);
    if( isYMD )
        sprintf(tmStr,"20%02d/%02d/%02d %02d:%02d:%02d", tm.nYear,tm.nMonth,tm.nDay,tm.nHour,tm.nMin,tm.nSec );    
    else
        sprintf(tmStr,"%02d:%02d:%02d", tm.nHour,tm.nMin,tm.nSec );    
   return tmStr;
}



